# -*- coding: utf-8 -*-

###################################################
# LOCAL import
###################################################
from Plugins.Extensions.IPTVPlayer.components.iptvplayerinit import TranslateTXT as _
from Plugins.Extensions.IPTVPlayer.components.ihost import CHostBase, CBaseHostClass, CDisplayListItem
from Plugins.Extensions.IPTVPlayer.tools.iptvtools import printDBG, IsExecutable, printExc, byteify
from Plugins.Extensions.IPTVPlayer.tools.iptvtypes import strwithmeta
from Plugins.Extensions.IPTVPlayer.tools.iptvfilehost import IPTVFileHost
from Plugins.Extensions.IPTVPlayer.libs.youtubeparser import YouTubeParser
from Plugins.Extensions.IPTVPlayer.components.iptvplayerinit import TranslateTXT as _
###################################################

###################################################
# FOREIGN import
###################################################
try:
    import json
except Exception:
    import simplejson as json
import re
import urllib
from Components.config import config, ConfigDirectory, getConfigListEntry
###################################################

###################################################
# Config options for HOST
###################################################
config.plugins.iptvplayer.Sciezkaurllist = ConfigDirectory(default="/hdd/")


def GetConfigList():
    optionList = []
    optionList.append(getConfigListEntry(_("Sort by:"), config.plugins.iptvplayer.ytSortBy))
    optionList.append(getConfigListEntry(_("Path to ytlist.txt, urllist.txt"), config.plugins.iptvplayer.Sciezkaurllist))
    optionList.append(getConfigListEntry(_("Video format:"), config.plugins.iptvplayer.ytformat))
    optionList.append(getConfigListEntry(_("Default video quality:"), config.plugins.iptvplayer.ytDefaultformat))
    optionList.append(getConfigListEntry(_("Use default video quality:"), config.plugins.iptvplayer.ytUseDF))
    optionList.append(getConfigListEntry(_("Age-gate bypass:"), config.plugins.iptvplayer.ytAgeGate))
    # temporary, the ffmpeg must be in right version to be able to merge file without transcoding
    # checking should be moved to setup
    if IsExecutable('ffmpeg'):
        optionList.append(getConfigListEntry(_("Allow dash format:"), config.plugins.iptvplayer.ytShowDash))
        if config.plugins.iptvplayer.ytShowDash.value != 'false':
            optionList.append(getConfigListEntry(_("Allow VP9 codec:"), config.plugins.iptvplayer.ytVP9))
    return optionList
###################################################
###################################################


def gettytul():
    return 'https://youtube.com/'


class Youtube(CBaseHostClass):

    def __init__(self):
        printDBG("Youtube.__init__")
        CBaseHostClass.__init__(self, {'history': 'ytlist', 'cookie': 'youtube.cookie'})
        self.UTLIST_FILE = 'ytlist.txt'
        self.DEFAULT_ICON_URL = 'https://www.vippng.com/png/full/85-853653_patreon-logo-png-transparent-background-youtube-logo.png'
        self.MAIN_GROUPED_TAB = [{'category': 'from_file', 'title': _("User links"), 'desc': _("User links stored in the ytlist.txt file.")},
                                 {'category': 'search', 'title': _("Search"), 'desc': _("Search youtube materials "), 'search_item': True},
                                 {'category': 'feeds', 'title': _("Trending"), 'desc': _("Browse youtube trending feeds")},
                                 {'category': 'search_history', 'title': _("Search history"), 'desc': _("History of searched phrases.")}]

        self.SEARCH_TYPES = [(_("Video"), "video"),
                               (_("Channel"), "channel"),
                               (_("Playlist"), "playlist"),
                              #(_("Movie"),    "movie"   ),
                               (_("Live"), "live")]
                              #("Program",            "show"    ),
                              #("traylist",           "traylist"),
        self.ytp = YouTubeParser()
        self.currFileHost = None

    def _getCategory(self, url):
        printDBG("Youtube._getCategory")
        if '/playlist?list=' in url:
            category = 'playlist'
        elif url.split('?')[0].endswith('/playlists'):
            category = 'playlists'
        elif None != re.search('/watch\?v=[^\&]+?\&list=', url):
            category = 'traylist'
        elif 'user/' in url or (('channel/' in url or '/c/' in url) and not url.endswith('/live')):
            category = 'channel'
        else:
            category = 'video'
        return category

    def listMainMenu(self):
        printDBG("Youtube.listsMainMenu")
        for item in self.MAIN_GROUPED_TAB:
            params = {'name': 'category'}
            params.update(item)
            self.addDir(params)

    def listCategory(self, cItem, searchMode=False):
        printDBG("Youtube.listCategory cItem[%s]" % cItem)

        sortList = True
        filespath = config.plugins.iptvplayer.Sciezkaurllist.value
        groupList = True
        if 'sub_file_category' not in cItem:
            self.currFileHost = IPTVFileHost()
            self.currFileHost.addFile(filespath + self.UTLIST_FILE, encoding='utf-8')
            tmpList = self.currFileHost.getGroups(sortList)
            if 0 < len(tmpList):
                params = dict(cItem)
                params.update({'sub_file_category': 'all', 'group': 'all', 'title': _("--All--")})
                self.addDir(params)
            for item in tmpList:
                if '' == item:
                    title = _("--Other--")
                else:
                    title = item
                params = dict(cItem)
                params.update({'sub_file_category': 'group', 'title': title, 'group': item})
                self.addDir(params)
        else:
            if 'all' == cItem['sub_file_category']:
                tmpList = self.currFileHost.getAllItems(sortList)
                for item in tmpList:
                    params = dict(cItem)
                    category = self._getCategory(item['url'])
                    params.update({'good_for_fav': True, 'title': item['full_title'], 'url': item['url'], 'desc': item['url'], 'category': category})
                    if 'video' == category:
                        self.addVideo(params)
                    elif 'more' == category:
                        self.addMore(params)
                    else:
                        self.addDir(params)
            elif 'group' == cItem['sub_file_category']:
                tmpList = self.currFileHost.getItemsInGroup(cItem['group'], sortList)
                for item in tmpList:
                    if '' == item['title_in_group']:
                        title = item['full_title']
                    else:
                        title = item['title_in_group']
                    params = dict(cItem)
                    category = self._getCategory(item['url'])
                    params.update({'good_for_fav': True, 'title': title, 'url': item['url'], 'desc': item['url'], 'category': category})
                    if 'video' == category:
                        self.addVideo(params)
                    elif 'more' == category:
                        self.addMore(params)
                    else:
                        self.addDir(params)

    def listItems(self, cItem):
        printDBG('Youtube.listItems cItem[%s]' % (cItem))
        category = cItem.get("category", '')
        url = cItem.get("url", '')
        page = cItem.get("page", '1')

        if "playlists" == category:
            self.currList = self.ytp.getListPlaylistsItems(url, category, page, cItem)

        for idx in range(len(self.currList)):
            if self.currList[idx]['category'] in ["channel", "playlist", "movie", "traylist"]:
                self.currList[idx]['good_for_fav'] = True

    def listFeeds(self, cItem):
        printDBG('Youtube.listFeeds cItem[%s]' % (cItem))
        if cItem['category'] == "feeds_video":
            sts, data = self.cm.getPage(cItem['url'])
            data2 = self.cm.ph.getAllItemsBeetwenMarkers(data, "videoRenderer", "watchEndpoint")
            for item in data2:
                url = "https://www.youtube.com/watch?v=" + self.cm.ph.getDataBeetwenMarkers(item, 'videoId":"', '","thumbnail":', False)[1]
                icon = self.cm.ph.getDataBeetwenMarkers(item, '},{"url":"', '==', False)[1]
                title = self.cm.ph.getDataBeetwenMarkers(item, '"title":{"runs":[{"text":"', '"}]', False)[1]
                desc = _("Channel") + ': ' + self.cm.ph.getDataBeetwenMarkers(item, 'longBylineText":{"runs":[{"text":"', '","navigationEndpoint"', False)[1] + "\n" + _("Release:") + ' ' + self.cm.ph.getDataBeetwenMarkers(item, '"publishedTimeText":{"simpleText":"', '"},"lengthText":', False)[1] + "\n" + _("Duration:") + ' ' + self.cm.ph.getDataBeetwenMarkers(item, '"lengthText":{"accessibility":{"accessibilityData":{"label":"', '"}},"simpleText":', False)[1] + "\n" + self.cm.ph.getDataBeetwenMarkers(item, '"viewCountText":{"simpleText":"', '"},"navigationEndpoint":', False)[1]
                params = {'title': title, 'url': url, 'icon': icon, 'desc': desc}
                self.addVideo(params)
        else:
           title = _("Trending")
           url = "https://www.youtube.com/feed/trending"
           params = {'category': 'feeds_video', 'title': title, 'url': url}
           self.addDir(params)
           title = _("Music")
           url = "https://www.youtube.com/feed/trending?bp=4gINGgt5dG1hX2NoYXJ0cw%3D%3D"
           params = {'category': 'feeds_video', 'title': title, 'url': url}
           self.addDir(params)
           title = _("Games")
           url = "https://www.youtube.com/feed/trending?bp=4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D"
           params = {'category': 'feeds_video', 'title': title, 'url': url}
           self.addDir(params)
           title = _("Movies")
           url = "https://www.youtube.com/feed/trending?bp=4gIKGgh0cmFpbGVycw%3D%3D"
           params = {'category': 'feeds_video', 'title': title, 'url': url}
           self.addDir(params)

    def getVideos(self, cItem):
        printDBG('Youtube.getVideos cItem[%s]' % (cItem))

        category = cItem.get("category", '')
        url = strwithmeta(cItem.get("url", ''))
        page = cItem.get("page", '1')

        if "channel" == category:
            if not ('browse' in url) and (not 'ctoken' in url):
                if url.endswith('/videos'):
                    url = url + '?flow=list&view=0&sort=dd'
                else:
                    url = url + '/videos?flow=list&view=0&sort=dd'
            self.currList = self.ytp.getVideosFromChannelList(url, category, page, cItem)
        elif "playlist" == category:
            self.currList = self.ytp.getVideosFromPlaylist(url, category, page, cItem)
        elif "traylist" == category:
            self.currList = self.ytp.getVideosFromTraylist(url, category, page, cItem)
        else:
            printDBG('YTlist.getVideos Error unknown category[%s]' % category)

    def listSearchResult(self, cItem, pattern, searchType):
        page = cItem.get("page", '1')
        url = cItem.get("url", "")

        if url:
            printDBG("URL ricerca -----------> %s" % url)
            tmpList = self.ytp.getSearchResult(urllib.quote_plus(pattern), searchType, page, 'search', config.plugins.iptvplayer.ytSortBy.value, url)
        else:
            tmpList = self.ytp.getSearchResult(urllib.quote_plus(pattern), searchType, page, 'search', config.plugins.iptvplayer.ytSortBy.value)

        for item in tmpList:
            item.update({'name': 'category'})
            if 'video' == item['type']:
                self.addVideo(item)
            elif 'more' == item['type']:
                self.addMore(item)
            else:
                if item['category'] in ["channel", "playlist", "movie", "traylist"]:
                    item['good_for_fav'] = True
                self.addDir(item)

    def getLinksForVideo(self, cItem):
        printDBG("Youtube.getLinksForVideo cItem[%s]" % cItem)
        urlTab = self.up.getVideoLinkExt(cItem['url'])
        if config.plugins.iptvplayer.ytUseDF.value and 0 < len(urlTab):
            return [urlTab[0]]
        return urlTab

    def getFavouriteData(self, cItem):
        printDBG('Youtube.getFavouriteData')
        return json.dumps(cItem)

    def getLinksForFavourite(self, fav_data):
        printDBG('Youtube.getLinksForFavourite')
        links = []
        try:
            cItem = byteify(json.loads(fav_data))
            links = self.getLinksForVideo(cItem)
        except Exception:
            printExc()
            return self.getLinksForVideo({'url': fav_data})
        return links

    def setInitListFromFavouriteItem(self, fav_data):
        printDBG('Youtube.setInitListFromFavouriteItem')
        try:
            params = byteify(json.loads(fav_data))
        except Exception:
            params = {}
            printExc()
        self.addDir(params)
        return True

    def handleService(self, index, refresh=0, searchPattern='', searchType=''):
        printDBG('Youtube.handleService start')

        CBaseHostClass.handleService(self, index, refresh, searchPattern, searchType)

        name = self.currItem.get("name", '')
        category = self.currItem.get("category", '')
        printDBG("Youtube.handleService: ---------> name[%s], category[%s] " % (name, category))
        self.currList = []

        if None == name:
            self.listMainMenu()
        elif 'from_file' == category:
            self.listCategory(self.currItem)
        elif category in ["channel", "playlist", "movie", "traylist"]:
            self.getVideos(self.currItem)
        elif category.startswith("feeds"):
            self.listFeeds(self.currItem)
        elif category == 'playlists':
            self.listItems(self.currItem)
        #SEARCH
        elif category in ["search", "search_next_page"]:
            cItem = dict(self.currItem)
            cItem.update({'search_item': False, 'name': 'category'})
            self.listSearchResult(cItem, searchPattern, searchType)
        #HISTORIA SEARCH
        elif category == "search_history":
            self.listsHistory({'name': 'history', 'category': 'search'}, 'desc', _("Type: "))
        else:
            printExc()

        CBaseHostClass.endHandleService(self, index, refresh)

    def getSuggestionsProvider(self, index):
        printDBG('Youtube.getSuggestionsProvider')
        from Plugins.Extensions.IPTVPlayer.suggestions.google import SuggestionsProvider
        return SuggestionsProvider(True)


class IPTVHost(CHostBase):

    def getSearchTypes(self):
        return self.host.SEARCH_TYPES

    def __init__(self):
        CHostBase.__init__(self, Youtube(), True, [CDisplayListItem.TYPE_VIDEO, CDisplayListItem.TYPE_AUDIO])
